package virtualstock.game;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import virtualstock.exception.GameNotFoundException;
import virtualstock.exception.InvalidParameterException;
import virtualstock.exception.PlayerNotFoundException;
import virtualstock.exception.PortfolioNotFoundException;
import virtualstock.exception.StockNotFoundException;
import virtualstock.request.GameController;
import virtualstock.request.PlayerController;
import virtualstock.request.PortfolioController;
import virtualstock.request.StockController;
import virtualstock.request.TransactionController;
import virtualstock.util.GameDetails;
import virtualstock.util.PlayerDetails;
import virtualstock.util.PortfolioDetails;
import virtualstock.util.RankEntry;
import virtualstock.util.StockDetails;

/**
 * Servlet implementation class GamePlayServlet
 */
public class GamePlayServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	@EJB
	private GameController gameController;
	@EJB
	private StockController stockController;
	@EJB
	private PlayerController playerController;
	@EJB
	private PortfolioController portfolioController;
	@EJB
	private TransactionController transactionController;
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GamePlayServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    private List<RankEntry> getRanks(List<PlayerDetails> playerList, Long gameID) throws InvalidParameterException, GameNotFoundException, PlayerNotFoundException, PortfolioNotFoundException, StockNotFoundException{
    	List<RankEntry> ranks = new LinkedList<RankEntry>();
    	
    	Long playerID = null;
    	String firstName = null;
    	String lastName = null;
    	BigDecimal portfolioValue = null;
    	for(PlayerDetails player : playerList){
    		playerID = player.getPlayerID();
    		firstName = player.getFirstName();
    		lastName = player.getLastName();
    		//calculate portfolio value
    		PortfolioDetails portfolio = portfolioController.getPortfolioDetailsByGameAndPlayer(gameID, playerID);
    		BigDecimal sumValue = new BigDecimal(0);
    		BigDecimal currentBalance = portfolio.getBalance();
    		//calculate stock value
    		Map<Long, Integer> stockShares = transactionController.getStocksInPortfolio(portfolio.getPortfolioID());
    		for(Map.Entry<Long, Integer> entry : stockShares.entrySet()){
    			Long stockID = entry.getKey();
    			int share = entry.getValue();
    			StockDetails stock = stockController.getStockDetails(stockID);
    			BigDecimal value = stock.getCurrentPrice().multiply(new BigDecimal(share));
    			sumValue = sumValue.add(value);
    		}
    		sumValue = sumValue.add(currentBalance);
    		RankEntry rankEntry = new RankEntry(playerID, lastName, firstName, sumValue);
    		ranks.add(rankEntry);
    	}
    	Collections.sort(ranks);
    	return ranks;
    }
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    	PrintWriter out = response.getWriter();
    	Long gameID = new Long((String) request.getParameter("gameID"));
    	
		//redirect to game page
		//collect information about the game
		//all stock available in this game
		List<StockDetails> stockList = stockController.getAllStocks();
		//all players involved in this game
		List<PlayerDetails> playerList = null;
		GameDetails gameDetail = null;
		try {
			playerList = (List<PlayerDetails>)playerController.getPlayersOfGame(gameID);
			gameDetail = gameController.getGameDetails(gameID);
		} catch (InvalidParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch(GameNotFoundException ex){
			ex.printStackTrace();
		}
		
		PortfolioDetails portfolioDetails = null;
		PlayerDetails playerDetails = (PlayerDetails) request.getSession().getAttribute("playerDetails");
		try {
			portfolioDetails = portfolioController.getPortfolioDetailsByGameAndPlayer(gameID, playerDetails.getPlayerID());
		} catch (InvalidParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (GameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PlayerNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PortfolioNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		HashMap<StockDetails, Integer> stockShareMap = new HashMap<StockDetails, Integer>();
		try {
			HashMap<Long, Integer> stockIDShareMap = transactionController.getStocksInPortfolio(portfolioDetails.getPortfolioID());
			for (Iterator<Long> it = stockIDShareMap.keySet().iterator(); it.hasNext(); ) {
				Long stockID = it.next();
				StockDetails details = stockController.getStockDetails(stockID);
				stockShareMap.put(details, stockIDShareMap.get(stockID));
			}
		} catch (InvalidParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PortfolioNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (StockNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//get all the players' portfolio value
		List<RankEntry> ranks = null;
		System.out.println("!!!!!!!!!!!!!!!!!!!!!: gamePlayservlet");
		try {
			ranks = this.getRanks(playerList, gameID);
			System.out.println(ranks);
		} catch (InvalidParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (GameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PlayerNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PortfolioNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (StockNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		//add to session
		request.setAttribute("stockShareMap", stockShareMap);
		request.setAttribute("currentGame", gameDetail);
		request.setAttribute("playerListInGame", playerList);
		request.setAttribute("stockList", stockList);
		request.setAttribute("portfolioDetails", portfolioDetails);
		request.setAttribute("rankList", ranks);
		request.getSession().setAttribute("portfolio", portfolioDetails);
		request.getSession().setAttribute("currentGame", gameDetail);
		request.getSession().setAttribute("playerListInGame", playerList);
		request.getRequestDispatcher("gamePage.jsp").forward(request, response);
    }
    
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

}
